Crate ril

source ·
Expand description

The Rust Imaging Library. A performant and high-level image processing crate for Rust.

See benchmarks and more by viewing the README. It should also be noted that the README is updated more frequently than the documentation.

Similarly, you can see the changelog here.

Installation

The MSRV (Minimum Supported Rust Version) of this crate is v1.61.0.

Add the following to your Cargo.toml dependencies:

ril = { version = "0", features = ["all"] ]

Installing from GitHub

You can also use the unstable but latest version by installing from GitHub:

ril = { git = "https://github.com/jay3332/ril", branch = "main", features = ["all"] }

Using cargo add

If you have cargo >= 1.62.0, you can use cargo add ril --features=all.

Cargo Features

RIL currently depends on a few dependencies for certain features - especially for various image encodings. By default RIL comes with no encoding dependencies but with the text and resize dependencies, which give you text and resizing capabilities respectively.

You can use the all feature to enable all features, including encoding features. This enables the widest range of image format support, but adds a lot of dependencies you may not need.

For every image encoding that requires a dependency, a corresponding feature can be enabled for it:

EncodingFeatureDependenciesDefault?
PNG and APNGpngpngno
JPEGjpegjpeg-decoder, jpeg-encoderno
GIFgifgifno
WebPwebplibwebp-sys2no

Other features:

DescriptionFeatureDependenciesDefault?
Font/Text Renderingtextfontdueyes
Image Resizingresizefast_image_resizeyes
Color Quantization (using NeuQuant)quantizecolor_quantyes
Gradientsgradientcolorgradyes
Enable all features,
including all encoding features
allno

WebP Support limitations

WebP support uses libwebp, which is a native library. This means that if you try to use the webp feature when compiling to a WebAssembly target, it might fail. We plan on making a pure-Rust port of libwebp in the future.

For ease of use, the all-pure feature is provided, which is the equivalent of all minus the webp feature.

Getting Started

Import the prelude which brings commonly used types and crucial traits into scope:

use ril::prelude::*;

Because all errors from this crate are of the same type, ril provides a Result type which you can use in any function that leverages ril, such as the main function:

use ril::prelude::*;

fn main() -> ril::Result<()> {
    // code goes here...

    Ok(())
}

Now you can use the ? operator on anything that returns a Result for convenience.

Brief Guide

A quick guide and overview of ril’s interface.

Opening an image

The open method should suit your needs:

let image = Image::<Rgb>::open("my_image.png")?;

The sole argument can be anything that implements AsRef<Path>, such as a string or a file.

You might have also noticed that Image is generic with one type parameter, which can be anything that implements Pixel. It represents what type of pixel this image has - in this case, the image has RGB pixels.

Common pixel formats are Rgb (colored) and Rgba (colored with transparency), which are found in the prelude. There are also grayscale counterparts, such as L.

Reading from a byte stream

You can also read from raw bytes using [from_bytes][Image::decode_from_bytes]:

let bytes = include_bytes!("image.png") as &[u8]; // Replace this with your own image data
let image = Image::<Rgb>::from_bytes(ImageFormat::Png, bytes)?;

The first argument is the encoding of the image, and the second is a slice of bytes, or anything that implements [AsRef<[u8]>].

You can also use from_bytes_inferred to infer the format from the byte slice without having to explicitly provide an encoding:

let image = Image::<Rgb>::from_bytes_inferred(bytes)?;

Creating your own image

You can create your own image using the Image::new method:

let image = Image::new(256, 256, Rgb::new(255, 0, 0));

The above creates a 256x256 RGB image with all pixels set to red.

The first argument is the width of the image, the second is the height, and the third is the fill color. The pixel type of the image can be inferred from this argument, which is why we don’t have to specify it explicitly as a type argument - Rust type inference is powerful and infers this for us.

The from_fn method

The from_fn method is a shortcut for creating an image from a function:

let image = Image::from_fn(256, 256, |x, y| {
    // Do something, maybe with `x` and `y`, and return a pixel
    Rgb::new(x as u8, y as u8, 0)
});

The above is just an example. You specify the width, height, and the function that generates the pixels. It should take two parameters - x and y, which specify the position of the pixel to generate - and return a pixel.

Encoding and saving images

You can encode and save an image to a file with the save method:

// Here's the red image from before:
let image = Image::new(256, 256, Rgb::new(255, 0, 0));

image.save(ImageFormat::Png, "output.png")?;

The first argument is the encoding of the image, and the second is the path to the file.

You may have noticed this is a bit repetitive, and that it is possible to infer the encoding from the file extension. In cases like this, you can use the slightly slower save_inferred method:

image.save_inferred("output.png")?;

Now, you do not have to explicitly specify the encoding as it is inferred from the output path.

Encoding and saving images to memory

You can encode images to a memory buffer by using the encode method:

let mut out = Vec::new();
image.encode(ImageFormat::Png, &mut out)?;

// Do something with `out`

The first argument is the encoding of the image, and the second is the output buffer that must implement Write.

There is no filename to infer the encoding from, so in this case you have to explicitly specify the encoding.

Manipulating images

Now that you know how to create and save images, let’s look at some of the ways we can modify them!

Inverting images

A common manipulation method would be inverting every pixel in the image. To do this, there are two methods which you can use:

  • invert: Inverts the image in-place
  • inverted: Consumes the image and returns a new image with the inverted pixels

A common pattern you’ll see in this crate is that many methods have an in-place method and a not-in-place counterpart, in which the former can be useful for method chaining. One usually does not have any memory or performance benefits than the other.

Anyhow, here’s how you’d invert an image:

let mut image = Image::new(256, 256, Rgb::new(255, 0, 0));
image.invert();
image.save_inferred("output.png")?;

(255, 0, 0) (red) inverts to (0, 255, 255) (cyan), so that should be the color of the output image.

We can also use inverted to use method chaining:

Image::new(256, 256, Rgb::new(255, 0, 0))
    .inverted()
    .save_inferred("output.png")?;

Seems to be a bit cleaner than the first way, but it really just comes down to preference… and whether or not you have ownership of the image object - you likely want to stay away from cloning images for no benefit as it is a very expensive operation.

TODO: finish guide

Modules

Encloses most drawing implementations and drawable objects.
Houses Encoder, Decoder, and frame iterator traits.
Contains encoder and decoder implementations for various image formats.
Common error types.
Handles rendering and logic of gradients.
Encloses pixel-related traits and pixel type implementations.
The crate prelude exports. Importing this with a wildcard will import most items from RIL that can be useful for image processing, along with bringing crucial traits into scope.
Quantizes unpaletted pixel data to paletted data by quantizing the colors into a palette.
Implements the animated image and image sequence interface.
Implements the font/text rasterizing and layout interface.

Structs

Represents a single-bit pixel that represents either a pixel that is on or off.
Represents a shape border.
An ellipse, which could be a circle.
Represents a single font along with its alternatives used to render text. Currently, this supports TrueType and OpenType fonts.
Represents a frame in an image sequence. It encloses an Image and extra metadata about the frame.
A high-level image representation.
Represents a sequence of image frames such as an animated image.
Represents an L, or luminance pixel that is stored as only one single number representing how bright, or intense, the pixel is.
A line.
A linear gradient.
Represents a paletted pixel, holding an index to a palette of Rgb colors represented as a &'p [Rgb], where 'p is the lifetime of the palette.
Represents a paletted pixel, holding an index to a palette of Rgba colors represented as a &'p [Rgba], where 'p is the lifetime of the palette.
Pastes or overlays an image on top of another image.
A polygon.
Configuration options regarding behavior of quantization.
A rectangle.
Represents an RGB pixel.
Represents an RGBA pixel.
Represents a high-level text layout that can layout text segments, maybe with different fonts.
Represents a text segment that can be drawn.

Enums

Represents whether a border is inset, outset, or if it lays in the center.
Represents an arbitrary color type. Note that this does not store the bit-depth or the type used to store the value of each channel, although it can specify the number of channels.
The method used to dispose a frame before transitioning to the next frame in an image sequence.
Represents a pixel type that is dynamically resolved.
Represents any one of the different types of frame iterators, compacted into one common enum with common methods.
Represents a subpixel of a dynamic pixel.
Represents an error that occurs within the crate.
Represents where text is anchored horizontally.
Represents the underlying encoding format of an image.
Color blending mode
Interpolation mode
Determines how many times an image sequence should repeat itself, or if it should repeat infinitely.
The behavior to use when overlaying images on top of each other.
A filtering algorithm that is used to resize an image.
Represents where text is anchored vertically.
Determines how text should be wrapped.

Traits

Represents a pixel that supports alpha, or transparency values.
Represents an image with multiple channels, called bands.
Low-level decoder interface around an image format.
A common trait for all objects able to be drawn on an image.
Low-level encoder interface around an image format.
Represents the lazy decoding of frames from an encoded image sequence, such as an animated image.
A trait representing a paletted pixel. Pixel::Subpixel is the type of the palette index.
Represents any type of pixel in an image.
A trait representing all pixels that can be safely represented as either RGB or RGBA true color.

Type Definitions

A shortcut type equivalent to Result<T, ril::Error>.